{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 获取前n个主成分\n",
    "> 上一节以二维线性方程为例，实际获取的只是第一主成分，本节将扩展到n+1维中，获取前n个主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.empty((100, 2))\n",
    "X[:,0] = np.random.uniform(0., 100., size=100)\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    return X - np.mean(X, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:,0], X[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 上一节得到的求解第1主成分的方法封装"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    return np.sum((X.dot(w)**2)) / len(X)\n",
    "\n",
    "def df(w, X):\n",
    "    return X.T.dot(X.dot(w)) * 2. / len(X)\n",
    "\n",
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "'''获取第一个主成分'''\n",
    "def first_component(X, initial_w, eta, n_iters = 1e4, epsilon=1e-8):\n",
    "    \n",
    "    w = direction(initial_w) \n",
    "    cur_iter = 0\n",
    "\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w, X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w) \n",
    "        if(abs(f(w, X) - f(last_w, X)) < epsilon):\n",
    "            break\n",
    "            \n",
    "        cur_iter += 1\n",
    "\n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.7766237 , 0.62996478])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_w = np.random.random(X.shape[1])\n",
    "eta = 0.01\n",
    "w = first_component(X, initial_w, eta)\n",
    "w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取前n个主成分\n",
    "> 在获取第1主成分后，要获取第二个主成分，只需要将数据在第一个主成分上的分量去掉，然后对剩下的数据再求一次主成分即为第2主成分，后面的主成分获取也是类似的方法\n",
    "![将第一个主成分从数据中拿掉](images/将第一个主成分从数据中拿掉.png)\n",
    "\n",
    ">在新的数据上求第1主成分，即为原始数据的第2主成分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 下面从原始数据X中把第一主成分全部去掉，得到计算第2主成分需要的数据。这是方法1，下面有方法2，可以简化为向量点乘\n",
    "X2 = np.empty(X.shape)\n",
    "for i in range(len(X)):\n",
    "    X2[i] = X[i] - X[i].dot(w) * w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 方法2：直接用向量点乘计算效果和上面循环相减的结果是一样地\n",
    "X2 = X - X.dot(w).reshape(-1, 1) * w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.6299673 , -0.77662166])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w2 = first_component(X2, initial_w, eta)\n",
    "w2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.2462281718270702e-06"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.dot(w2) # 结果接近0，证明两个向量是互相垂直地，即相邻的两个主成分向量是互相垂直的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''获取前n个主成分'''\n",
    "def first_n_components(n, X, eta=0.01, n_iters = 1e4, epsilon=1e-8):\n",
    "    X_pca = X.copy()\n",
    "    X_pca = demean(X_pca)\n",
    "    res = []\n",
    "    for i in range(n):\n",
    "        initial_w = np.random.random(X_pca.shape[1]) # 生成初始搜索点\n",
    "        w = first_component(X_pca, initial_w, eta) # 不断地对当前的数据求第1主成分，就得到原始数据的第i个主成分\n",
    "        res.append(w)\n",
    "        \n",
    "        X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w # 去除本次得到的主成分分量，剩下的数据在下一次循环中再进行求第1主成分\n",
    "        \n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([0.77477398, 0.63223831]), array([ 0.63224099, -0.7747718 ])]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = first_n_components(2, X) # 输入是二维数据所以只有两个主成分。有几个特征(几列)就有几个主成分\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.448300377295599e-06"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res[0].dot(res[1]) # 非常接近0， 可以看出相邻的两个主成分是互相垂直的"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
